#ifndef _OPT_PLUGIN_H_INCLUDED_
#define _OPT_PLUGIN_H_INCLUDED_

// device OLED dimensions and buttons count

#define IMG_X_SIZE 96
#define IMG_Y_SIZE 96
#define MAX_BUTTON 3 

// string information to be provided by plugin

#define INFO_KEY				0
#define INFO_NAME				1
#define INFO_DESC				2
#define INFO_AUTHOR				3
#define INFO_EMAIL				4
#define INFO_HOMEPAGE			5
#define INFO_APPLICATION		6
#define INFO_APPLICATION_CONFIG	7

// integer information to be provided by plugin
#define INFO_FUNCTIONS		10
#define INFO_DELAY			11
#define INFO_MAIN_FUNCTION  12

// HICON information to be provided by plugin
#define INFO_ICON16			20
#define INFO_ICON32			21
#define INFO_DEFIMAGE		22

// information if plugin has values to be saved in registry
#define INFO_HAS_PROPERTIES			0x100-1
#define INFO_HAS_SHARED_PROPERTIES	0x200-1

// properties bases. first has PLUGIN_PROPERTIES index, second PLUGIN_PROPERTIES+1, and so on
#define PLUGIN_PROPERTIES			0x100
#define PLUGIN_SHARED_PROPERTIES	0x200

// these are events plugin can react on. 
#define EVENT_ACTIVATE		1
#define EVENT_DEACTIVATE	2

#define MAX_INFO_STRING     256
#define MAX_PROPERTY_LENGTH 256

// Defines to simplify GetInfo method programming

#define GET_INFO( INDEX, VALUE )						\
	if ( index == INDEX ){								\
		return (LPARAM)(VALUE);							\
	}

#define GET_ICON_SIZE( INDEX, VALUE, SIZE )				\
	if ( index == INDEX ){								\
		return (LPARAM)::LoadImage ( g_hModule, VALUE, IMAGE_ICON, SIZE, SIZE, LR_DEFAULTCOLOR ); \
	}

#define GET_ICON( INDEX, VALUE )						\
	GET_ICON_SIZE(INDEX, VALUE, 0)

#define GET_ICON_EX( VALUE )							\
	GET_ICON_SIZE( INFO_ICON16, VALUE, 16 )				\
	GET_ICON_SIZE( INFO_ICON32, VALUE, 32 )				

#define GET_IMAGE( INDEX, VALUE )						\
	if ( index == INDEX ){								\
		return (LPARAM)::LoadImage ( g_hModule, VALUE, IMAGE_BITMAP, 0, 0, LR_DEFAULTCOLOR ); \
	}

// Defines to simplify GetProperty/SetProperty methods programming

#define GET_PROPERTY( INDEX, NAME, VALUE )				\
	if ( index == PLUGIN_PROPERTIES + INDEX ){			\
		strncpy( name, NAME, MAX_PROPERTY_LENGTH );		\
		strncpy( value, VALUE, MAX_PROPERTY_LENGTH );	\
		return TRUE;									\
	}

#define GET_INT_PROPERTY( INDEX, NAME, VALUE )			\
	if ( index == PLUGIN_PROPERTIES + INDEX ){			\
		strncpy( name, NAME, MAX_PROPERTY_LENGTH );		\
		itoa(VALUE,value,10);							\
		return TRUE;									\
	}

#define SET_PROPERTY( NAME, VALUE )						\
	if ( !strncmp(name, NAME, MAX_PROPERTY_LENGTH) ){	\
		VALUE = value;									\
		return TRUE;									\
	}

#define SET_INT_PROPERTY( NAME, VALUE )					\
	if ( !strncmp(name, NAME, MAX_PROPERTY_LENGTH) ){	\
		VALUE = atoi(value);							\
		return TRUE;									\
	}

#define GET_SHARED_PROPERTY( INDEX, NAME, VALUE )		\
	if ( index == PLUGIN_SHARED_PROPERTIES + INDEX ){	\
		strncpy( name, NAME, MAX_PROPERTY_LENGTH );		\
		strncpy( value, VALUE, MAX_PROPERTY_LENGTH );	\
		return TRUE;									\
	}


// This is the interface plugin should implement. Plugin DLL has Create and Delete methods exported,
// Create should return a pointer to class derived from OptimusMiniPlugin class, 
// Delete should release memory for created object.

class OptimusMiniPlugin
{
public:
	// called every INFO_DELAY ms or three times a second by default.
	// should return true if anything painted, false means previous image should be used.	
	// HDC:  has IMG_X_SIZE x IMG_Y_SIZE dimensions
	virtual BOOL __stdcall Paint(HDC hdc) = 0;

	// called on keydown from device thread. should return fast.
	virtual void __stdcall OnKeyDown() = 0;

	// to collect INFO_* values from plugin
	virtual LPARAM __stdcall GetInfo(int index) = 0;

	// allows to get properties from plugin instance
	// index: from PLUGIN_PROPERTIES and PLUGIN_SHARED_PROPERTIES until false is return.
	// should return value and name (no longer then MAX_PROPERTY_LENGTH bytes)
	virtual BOOL __stdcall GetProperty(int index, char *name, char *value){ return FALSE; }

	// allows to set plugin instance properties
	// called for every name got with GetProperty with actial value from registry
	virtual BOOL __stdcall SetProperty(const char *name, const char *value){ return FALSE; }

	// shows plugin properties dialog.
	// should return true if properties has been changed.
	virtual BOOL __stdcall ShowProperties(HWND hwnd){ return FALSE; }

	// plugin life cicle is OnEvent(ACTIVATE) -> Paint(),Paint().. -> OnEvent(DEACTIVATE)
	// ACTIVATE/DEACTIVATE can be used to allocate resources requied for painting
	// should return TRUE. should return fast.
	virtual BOOL __stdcall OnEvent(int event){ return TRUE; }
};


// exported Create and Delete functions

  #ifdef PLUGIN_EXPORT
    #define PREFIX __declspec(dllexport)
    #pragma message("Export")
  #else
    #define PREFIX __declspec(dllimport)
    #pragma message("Import")
    #pragma comment(lib, "OptimusPluginShim.lib")
  #endif

  extern "C" PREFIX OptimusMiniPlugin *CreatePlugin( HMODULE hModule, int function, 
                                              LPARAM Reserved,
                                              WCHAR* managedPluginProgID);

  extern "C" PREFIX void DeletePlugin( OptimusMiniPlugin* lpPlugin );


#endif